﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using MAPIdotnet;
using Silvermoon.Controls.Forms;
using System.Diagnostics;

namespace OutlookHub.Models
{
    public class EMailContext : IDisposable
    {
        private Store currentStore;
        private Folder currentFolder;
        private List<Folder> folders;
        private MAPI mapi;
        private IEnumerable<Store> stores;
        private static EMailContext instance;
        private static object lockObject = new object();

        public static EMailContext Context
        {
            get
            {
                if (instance == null) instance = new EMailContext();
                return instance;
            }
        }

        public static void Close()
        {
            if (instance != null) instance.Dispose();
            instance = null;
        }


        private EMailContext()
            : base()
        {
            mapi = new MAPI();

        }

        public void Dispose()
        {
            lock (lockObject)
            {
                if (mapi != null) mapi.Dispose();
                mapi = null;
                CurrentFolder = null;
                CurrentStore = null;

                if (stores != null)
                {
                    foreach (var store in stores) store.Dispose();
                }

                stores = null;
                folders = null;
            }
            GC.SuppressFinalize(this);
        }

        ~EMailContext()
        {
            Dispose();
        }


        public static object LockObject { get { return lockObject; } }

        /// <summary>
        /// Gets the default email store. By default this is the store with the name "Hotmail", otherwise the first store in the list.
        /// </summary>
        public Store DefaultEMailStore
        {
            get
            {
                var store = EMailContext.Context.Stores.FirstOrDefault(c => (string.Compare("Hotmail", c.Name, true) == 0));
                if (store == null) store = EMailContext.Context.Stores.FirstOrDefault();
                return store;
            }
        }

        /// <summary>
        /// Gets the number of stores.
        /// </summary>
        public int StoreCount
        {
            get { return mapi.MessageStores.Length; }
        }

        /// <summary>
        /// Gets all available stores.
        /// </summary>
        public IEnumerable<Store> Stores
        {
            get
            {
                if (stores == null) stores = mapi.MessageStores.Select(s => new Store(s)).ToArray();
                return stores;
            }
        }

        /// <summary>
        /// Gets or sets the current application store.
        /// </summary>
        public Store CurrentStore
        {
            get
            {
                if (currentStore == null)
                {
                    currentStore = DefaultEMailStore;
                }
                return currentStore;
            }
            set
            {
                currentStore = value;
                currentFolder = null;
                folders = null;
            }
        }

        /// <summary>
        /// Gets or sets the current application folder.
        /// </summary>
        public Folder CurrentFolder
        {
            get
            {
                if (currentFolder == null)
                {
                    currentFolder = CurrentStore.ReceiveFolder;
                }
                return currentFolder;
            }

            set
            {
                if (currentFolder != value)
                {
                    currentStore = value != null ? value.Store : null;
                    currentFolder = value;
                }
            }
        }

        /// <summary>
        /// Gets all folders and subfolders in the current store
        /// </summary>
        public IEnumerable<Folder> Folders
        {
            get
            {
                if (folders == null)
                {
                    Folder folder = CurrentStore.RootFolder;
                    folders = folder.SubFolders.ToList();
                }
                return folders;
            }
        }

        /// <summary>
        /// Gets all messages in the current folder.
        /// </summary>
        public IEnumerable<Message> MailMessages
        {
            get
            {
                return CurrentFolder.Messages;
            }
        }

    }
}
